package org.yray.sip.config.sip;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.yray.sip.base.MsgEle;
import org.yray.sip.base.SipMsg;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Configuration
@EnableConfigurationProperties({ExtProperties.class})
public class ExtTable {

    final static String EXT_MAP_KEY = "SBC_EXT_MAP_KEY";
    final static String OUTER_EXT_MAP_KEY = "SBC_OUTER_EXT_MAP_KEY";
    final static Integer SCAN_EXT_REGISTER_TIME = 300000;
    //分机注册过期时间，30分钟，sip客户端一般5分钟左右会发送一次注册进行刷新

    private static Map<String,String> map=new HashMap<>();
    private static Map<String,String> extMap=new HashMap<>();
    private static Map<String,String> outerExtMap=new HashMap<>();
    static {
        map.put("","");
    }
    public  ExtProperties property;
    public ExtTable(ExtProperties property)
    {
        this.property=property;
    }


    private ExtTable() {
        /*Thread cleanerThread = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    Thread.sleep(SCAN_EXT_REGISTER_TIME);

                    clearCache();

                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        cleanerThread.setDaemon(true);
        cleanerThread.start();*/
    }

    /*private void clearCache () {
        String uuid = UUID.randomUUID().toString();
        String redisKey = "SBC_EXT_TABLE_CACHE_REDIS_LOCK_KEY";
        int lockTime = 4 * 60 * 1000;
        try {
            if (LockUtil.lock(redisKey, uuid, lockTime)) {
                clearExtMap(EXT_MAP_KEY);
                clearExtMap(OUTER_EXT_MAP_KEY);
            }
        } catch (Exception e) {
            log.error("ExtTable删除缓存失败，异常原因：{}", ExceptionUtils.getFullStackTrace(e));
        } finally {
            //释放锁
            LockUtil.releaseLock(redisKey, uuid);
        }

    }*/

    /*private void clearExtMap (String redisKey) {
        Map<Object, Object> extMap = StaticRedisUtil.staticRedisTemplate.opsForHash().entries(redisKey);
        if (!CollectionUtils.isEmpty(extMap)) {
            List<Object> needDeleteList = new ArrayList<>(extMap.size());
            for (Map.Entry<Object, Object> objectObjectEntry : extMap.entrySet()) {
                Object key = objectObjectEntry.getKey();
                CacheObject value = (CacheObject)objectObjectEntry.getValue();
                if (value.isExpired()) {
                    needDeleteList.add(key);
                }
            }
            if (!CollectionUtils.isEmpty(needDeleteList)) {
                Long delete = StaticRedisUtil.staticRedisTemplate.opsForHash().delete(redisKey, needDeleteList);
                log.info("缓存删除{}条", delete);
            }
        }
    }*/



    //sip:78005@172.130.13.31:56546
    public  static  String  putExtIpPort(String extIpPort, SipMsg sipMsg)
    {
        log.info("putExtIpPort={}",extIpPort);
        String[] eles=extIpPort.split(MsgEle.ELE_SEPARATOR);
        String ext=eles[1].split("@")[0];
        String ip=eles[1].split("@")[1];
        String port=eles[2];

        extMap.put(ext,ip+MsgEle.ELE_SEPARATOR+port);
//      StaticRedisUtil.staticRedisTemplate.opsForHash().put(EXT_MAP_KEY, ext, new CacheObject(ip+MsgEle.ELE_SEPARATOR+port, configProperty.extRegisterExpireTime));

        if (sipMsg != null) {
            outerExtMap.put(ext, sipMsg.getReceiveIp() + MsgEle.ELE_SEPARATOR + sipMsg.getReceivePort());
//          StaticRedisUtil.staticRedisTemplate.opsForHash().
//          put(OUTER_EXT_MAP_KEY, ext, new CacheObject(sipMsg.getReceiveIp() + MsgEle.ELE_SEPARATOR + sipMsg.getReceivePort(), configProperty.extRegisterExpireTime));
        }
        return ext;
    }

    /**
     * 查找分机注册时的外网端口
     * @param ext
     * @return
     */
    /*public static String findOuterPort (String ext) {
        CacheObject cacheObject = getOuterInfo(ext);
        if (cacheObject == null) {
            return null;
        }

        return cacheObject.getValue().toString().split(MsgEle.ELE_SEPARATOR)[1];
    }*/

    /**
     * 查找分机注册时外网ip
     * @param ext
     * @return
     */
    /*public static String findOuterIp (String ext) {
        CacheObject cacheObject = getOuterInfo(ext);
        if (cacheObject == null) {
            return null;
        }

        return cacheObject.getValue().toString().split(MsgEle.ELE_SEPARATOR)[0];
    }*/
    /*public static CacheObject getOuterInfo (String ext) {
        Object o = StaticRedisUtil.staticRedisTemplate.opsForHash().get(OUTER_EXT_MAP_KEY, ext);
        if (o == null) {
            return null;
        }
        CacheObject cacheObject = (CacheObject)o;
        return cacheObject;
    }*/

    /*public static String getIpPort(String ext)
    {
        Object o = StaticRedisUtil.staticRedisTemplate.opsForHash().get(EXT_MAP_KEY, ext);
        if (o != null) {
            CacheObject cacheObject = (CacheObject)o;
            Object value = cacheObject.getValue();
            return value.toString();
        }
        return "";
//        return extMap.get(ext);
    }*/

    /*public static String getIp(String ext)
    {
        String ipPort=getIpPort(ext);
        return ipPort.split(MsgEle.ELE_SEPARATOR)[0];
    }
    public static String getPort(String ext)
    {
        String ipPort=getIpPort(ext);
        return ipPort.split(MsgEle.ELE_SEPARATOR)[1];
    }*/

    /*public static JSONObject findInfoByExt (String ext) {
        String key = "FSC_EXT_PWD_KEY";

        Object o = StaticRedisUtil.staticRedisTemplate.opsForHash().get(key, ext);
        if (o != null) {
            return (JSONObject)o;
        } else {
            //如果查询是空，需要判断缓存是否失效了，如果这个节点正在更新缓存则可能存在问题
            Long expire = StaticRedisUtil.staticRedisTemplate.getExpire(key);
            if (expire != null && expire.longValue() == -2) {
                //如果返回-2，则表示是key不存在，睡眠1秒重新获取
                ThreadUtil.sleep(1000, TimeUnit.MILLISECONDS);
            }
            o = StaticRedisUtil.staticRedisTemplate.opsForHash().get(key, ext);
            if (o == null) {
                return null;
            } else {
                JSONObject jsonObject = (JSONObject)o;
                return jsonObject;
            }

        }
    }*/

   public static String findPasswordByExt(String ext)
    {
        return "123456";
    }

   /* public static String findFsIpByExt(String ext)
    {
        JSONObject infoByExt = findInfoByExt(ext);
        if (infoByExt != null) {
            return infoByExt.getString("fsIp");
        } else {
            return "";
        }
    }*/

    /**
     * 缓存对象value
     */
    public static class CacheObject implements Serializable {
        private Object value;
        private long expiryTime;

        private CacheObject(Object value, long expiryTime) {
            this.value = value;
            this.expiryTime = System.currentTimeMillis() + expiryTime;
        }

        boolean isExpired() {
            return System.currentTimeMillis() > expiryTime;
        }

        public Object getValue() {
            return value;
        }

        public void setValue(Object value) {
            this.value = value;
        }
    }

    /*public static String findSipExt(SipMsg sipMsg) {
        String ext = null;

        String str = new StringBuilder(sipMsg.getSipMap().get(MsgEle.TO)).append(sipMsg.getSipMap().get(MsgEle.FROM)).toString();
        //正常情况下TO和FROM里只会有一个符合分机格式，分机打分机会出现两个，需要取via里的地址
        List<String> any = RegexUtils.findAny(str, RegexUtils.REGEX_EXT + "@");
        if (any.size() == 1) {
            ext = StringUtils.replace(any.get(0).split(MsgEle.ELE_SEPARATOR)[1], "@", "");

        } else {
            //从服务器到软电话，如果是 100try、183、480，channel则取form的分机
            //如果是bye 取to的分机
            MsgType msgType = sipMsg.getMsgType();
            if (MsgType.TRYING.equals(msgType) ||
                    MsgType.PROGRESS183.equals(msgType) ||
                    MsgType.UNAVAILABLE480.equals(msgType) ||
                    MsgType.CANCEL.equals(msgType)) {
                str = RegexUtils.findOne(sipMsg.getSipMap().get(MsgEle.FROM), RegexUtils.REGEX_EXT + "@");
            } else {
                str = RegexUtils.findOne(sipMsg.getSipMap().get(MsgEle.TO), RegexUtils.REGEX_EXT + "@");
            }
            ext = StringUtils.replace(str.split(MsgEle.ELE_SEPARATOR)[1], "@", "");

        }
        if (StringUtils.isBlank(ext)) {
            log.error("通过sip报文解析出所属分机为空，sip报文：{}", sipMsg.getSipMap().toString());
        }
        return ext;
    }*/
}
